"""
脚本任务管理器
"""
from typing import Optional, List, Dict, Any
from datetime import datetime
from sqlalchemy import desc, or_
from .models import ScriptTask, Task
from .sqlalchemy_database import SQLAlchemyDatabaseManager

class ScriptTaskManager:
    def __init__(self):
        """
        初始化脚本任务管理器
        """
        self.db = SQLAlchemyDatabaseManager()

    def get_by_id(self, task_id: int) -> Optional[Dict[str, Any]]:
        """
        根据ID获取任务
        :param task_id: 任务ID
        :return: 任务信息字典或None
        """
        session = self.db.get_session()
        try:
            task = session.get(ScriptTask, task_id)
            return self._convert_model_to_dict(task) if task else None
        finally:
            session.close()

    def get_by_script_id(self, script_id: int) -> List[Dict[str, Any]]:
        """
        获取指定脚本的所有启用状态的任务
        :param script_id: 脚本ID
        :return: 任务列表
        """
        try:
            print(f"获取脚本任务，script_id={script_id}")
            session = self.db.get_session()
            try:
                # 联表查询任务信息，只获取启用状态的任务
                results = session.query(
                    Task, ScriptTask
                ).join(
                    ScriptTask, ScriptTask.task_id == Task.id
                ).filter(
                    ScriptTask.script_id == script_id,
                    Task.status == 1  # 只获取启用状态的任务
                ).all()
                
                tasks = []
                for task, script_task in results:
                    task_dict = self._convert_model_to_dict(task)
                    script_task_dict = self._convert_model_to_dict(script_task)
                    # 合并两个字典，保留脚本任务的特定字段
                    task_dict.update({
                        'script_task_id': script_task_dict['id'],
                        'script_id': script_task_dict['script_id'],
                        'task_id': script_task_dict['task_id'],
                        'script_task_status': script_task_dict['status']
                    })
                    tasks.append(task_dict)
                    
                print(f"获取到{len(tasks)}个启用状态的任务")
                return tasks
            finally:
                session.close()
        except Exception as e:
            import traceback
            print(f"获取脚本任务失败: {str(e)}\n{traceback.format_exc()}")
            raise

    def get_by_task_id(self, task_id: int) -> List[Dict[str, Any]]:
        """
        根据任务ID获取所有相关记录
        :param task_id: 任务ID
        :return: 记录列表
        """
        session = self.db.get_session()
        try:
            tasks = session.query(ScriptTask).filter(ScriptTask.task_id == task_id).all()
            return [self._convert_model_to_dict(task) for task in tasks]
        finally:
            session.close()

    def get_all(self, limit: int = None, offset: int = None) -> List[Dict[str, Any]]:
        """
        获取所有任务
        :param limit: 限制返回数量
        :param offset: 偏移量（用于分页）
        :return: 任务列表
        """
        session = self.db.get_session()
        try:
            query = session.query(ScriptTask)
            
            if limit is not None and offset is not None:
                query = query.limit(limit).offset(offset)
                
            tasks = query.all()
            return [self._convert_model_to_dict(task) for task in tasks]
        finally:
            session.close()

    def get_by_status(self, status: int) -> List[Dict[str, Any]]:
        """
        根据状态获取任务
        :param status: 任务状态
        :return: 任务列表
        """
        session = self.db.get_session()
        try:
            tasks = session.query(ScriptTask).filter(ScriptTask.status == status).all()
            return [self._convert_model_to_dict(task) for task in tasks]
        finally:
            session.close()

    def add(self, data: Dict[str, Any]) -> int:
        """
        添加新任务
        :param data: 任务数据
        :return: 新任务的ID
        """
        try:
            print(f"添加任务，数据: {data}")
            task = ScriptTask(**data)
            print(f"创建任务对象: {task.__dict__}")
            task_id = self.db.add(task)
            print(f"保存任务成功，ID: {task_id}")
            return task_id
        except Exception as e:
            import traceback
            print(f"添加任务失败: {str(e)}\n{traceback.format_exc()}")
            raise

    def add_task(self, script_id: int, task_id: int) -> int:
        """
        添加新任务（旧方法，保持兼容）
        :param script_id: 脚本ID
        :param task_id: 任务ID
        :return: 新任务的ID
        """
        now = datetime.now()
        data = {
            'script_id': script_id,
            'task_id': task_id,
            'status': 0,
            'create_at': now.strftime('%Y-%m-%d %H:%M:%S'),
            'update_at': int(now.timestamp())
        }
        return self.add(data)

    def update_task_status(self, task_id: int, status: int, error_message: str = None) -> bool:
        """
        更新任务状态
        :param task_id: 任务ID
        :param status: 新状态
        :param error_message: 错误信息
        :return: 是否成功
        """
        task = self.db.get_by_id(ScriptTask, task_id)
        if not task:
            return False
            
        task.status = status
        if error_message is not None:
            task.error_message = error_message
        task.update_at = int(datetime.now().timestamp())
        
        self.db.update_obj(task)
        return True

    def update_task_result(self, task_id: int, result: str) -> bool:
        """
        更新任务结果
        :param task_id: 任务ID
        :param result: 结果数据
        :return: 是否成功
        """
        task = self.db.get_by_id(ScriptTask, task_id)
        if not task:
            return False
            
        task.result = result
        task.update_at = int(datetime.now().timestamp())
        
        self.db.update_obj(task)
        return True

    def delete_task(self, task_id: int) -> bool:
        """
        删除任务
        :param task_id: 任务ID
        :return: 是否成功
        """
        task = self.db.get_by_id(ScriptTask, task_id)
        if not task:
            return False
            
        self.db.delete_obj(task)
        return True

    def delete_by_script_id(self, script_id: int) -> bool:
        """
        删除指定脚本的所有记录
        :param script_id: 脚本ID
        :return: 是否成功
        """
        try:
            print(f"删除脚本任务关联，script_id={script_id}")
            session = self.db.get_session()
            try:
                session.query(ScriptTask).filter(
                    ScriptTask.script_id == script_id
                ).delete(synchronize_session=False)
                session.commit()
                print(f"删除脚本任务关联成功")
                return True
            except Exception as e:
                session.rollback()
                raise
            finally:
                session.close()
        except Exception as e:
            import traceback
            print(f"删除脚本任务关联失败: {str(e)}\n{traceback.format_exc()}")
            raise

    def _convert_model_to_dict(self, model) -> Dict[str, Any]:
        """
        将模型对象转换为字典
        :param model: 模型对象
        :return: 字典
        """
        if not model:
            return {}
            
        # 获取模型的所有属性
        result = {}
        for column in model.__table__.columns:
            result[column.name] = getattr(model, column.name)
            
        return result
